package com.wuseguang.springcloud.service.impl;

import com.alibaba.fastjson.JSON;
import com.wuseguang.springcloud.Classcardservice.ClassCardFieldService;
import com.wuseguang.springcloud.Classcardservice.ClassCardService;
import com.wuseguang.springcloud.dao.jdbc.AttendClassTimeJdbc;
import com.wuseguang.springcloud.dao.jdbc.TeachingClassesTemplate;
import com.wuseguang.springcloud.dao.repository.AttendClassTimeRepository;
import com.wuseguang.springcloud.dao.repository.ClassDayRepository;
import com.wuseguang.springcloud.dao.repository.TimetableRepository;
import com.wuseguang.springcloud.entity.AttendClassTime;
import com.wuseguang.springcloud.entity.ClassDay;
import com.wuseguang.springcloud.entity.Timetable;
import com.wuseguang.springcloud.service.TimetableService;
import com.wuseguang.springcloud.util.CodeUtil;
import com.wuseguang.springcloud.util.DateUtil;
import com.wuseguang.springcloud.util.ExeclUtils;
import com.wuseguang.springcloud.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课表 服务实现类
 * </p>
 *
 * @author
 * @since 2019-12-07
 */
@Service
public class TimetableServiceImpl implements TimetableService {


    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private TeachingClassesTemplate teachingClassesTemplate;
    @Autowired
    private TimetableRepository timetableRepository;
    @Autowired
    private AttendClassTimeRepository attendClassTimeReoisutiry;
    @Autowired
    private ClassDayRepository classDayRepository;
    @Autowired
    private AttendClassTimeJdbc attendClassTimeJdbc;

    @Autowired
    private ClassCardService classCardService;

    @Autowired
    private ClassCardFieldService classCardFieldService;


    @Override
    public int exportLessonTemplate(HttpServletRequest httpRequest, HttpServletResponse response, Integer type, String teacherId, String schoolId) {

        logger.info("导出课表模板 TimetableServiceImpl -> exportLessonTemplate");
        //获取中文数字数字
        Map<String, String> numberMap = getMap();
        //查询课节sql
        String sql = "select day,second from class_day where school_id = ?";
        logger.info("查询该学校的课节 sql = {},schoolId = {}", sql, schoolId);
        Map<String, Object> map = null;
        try {
            map = teachingClassesTemplate.queryMap(sql, schoolId);
        } catch (Exception e) {
            logger.info("不存在课节");
            return 1;
        }
        //上课天数
        Integer day = Integer.valueOf(map.get("day").toString());
        //上课节数
        Integer second = Integer.valueOf(map.get("second").toString());
        //key
        String[] key = new String[(day * second) + 1];
        //values
        String[] value = new String[]{"className"};
        //数组下标
        int k = 1;
        key[0] = "班级/节次";
        //循环天数
        for (int i = 0; i < day; i++) {
            String mapKey = String.valueOf((i + 1));
            //循环节数
            for (int j = 0; j < second; j++) {
                key[k] = "星期" + numberMap.get(mapKey) + "第" + (j + 1) + "节";
                k++;
            }
        }
        //模板数据
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

        //如果为班级课表
        if (type == 1) {
            //查询这个老师班主任的班级
            sql = "select  ifnull(c.`second_name`,c.`name`)   className  from classes c  where c.class_teacher_id = ?";
            logger.info("查询这个老师班主任的班级 sql = {},class_teacher_id = {}", sql, teacherId);
            //要导出的班级数据
            list = teachingClassesTemplate.queryListMap(sql, teacherId);
        } else if (type == 2) {
            //查询这个老师班主任的班级
            sql = "select  ifnull(c.`second_name`,c.`name`)   className  from classes c  where c.school_id = ? GROUP BY `id` ";
            logger.info("查询这个全部班级 sql = {},school_id = {}", sql, schoolId);
            //要导出的班级数据
            list = teachingClassesTemplate.queryListMap(sql, schoolId);
        }

        try {
            ExeclUtils.downloadExcelMapTemplate(response, list, key, value, "课表模板");
        } catch (IOException e) {
            logger.info("课表模板错误,e", e);
        }
        return 0;
    }

    @Override
    public Result addClassDay(String schoolId, Integer day, Integer second, String[] classTime) {
        String sql = "DELETE FROM `class_day` WHERE `school_id` = ?";
        attendClassTimeJdbc.updateByParameter(sql, schoolId);
        //学校上课节次id
        Integer cdId = null;
        try {
            //学校上课节次实体
            ClassDay cd = new ClassDay();
            cd.setDay(day);
            cd.setSchoolId(Integer.valueOf(schoolId));
            cd.setSecond(second);
            //添加到数据库
            cdId = classDayRepository.save(cd).getId();
        } catch (Exception e) {
            logger.info("添加学校上课节失败 e ", e);
            return new Result(CodeUtil.FAILED_TO_ADD_SCHOOL_CLASS_SECTION);
        }


        sql = "delete FROM `attend_class_time` WHERE `school_id` = ?";
        attendClassTimeJdbc.updateByParameter(sql, schoolId);
        try {
            //学校上课时间集合
            List<AttendClassTime> actList = new ArrayList<AttendClassTime>();

            //循环上课时间
            for (int i = 0; i < classTime.length; i++) {
                //学校上课时间
                String[] time = classTime[i].split("-");
                //学校上课时间实体
                AttendClassTime act = new AttendClassTime();
                act.setSchoolId(Integer.valueOf(schoolId));
                act.setCurrentSection(i);
                act.setStartTime(time[0]);
                act.setEndTime(time[1]);
                actList.add(act);

            }
            attendClassTimeReoisutiry.saveAll(actList);
        } catch (Exception e) {
            logger.info("添加上课时间失败 e", e);
            classDayRepository.deleteById(cdId);
            return new Result(CodeUtil.FAILED_TO_ADD_SCHOOL_CLASS_SECTION);
        }
        String sql2 = "SELECT GROUP_CONCAT(id) string FROM bancard WHERE school_id=?";
        String s = attendClassTimeJdbc.queryString(sql2, new Object[]{schoolId});
        classCardFieldService.pushClassCard(s, "timetableflag", "1");
        classCardService.pushClassCard(s);
        return new Result();
    }

    @Override
    public Result searchTimetable(String schoolId, String timetable) {

        List<Map<String, Object>> errorList = new ArrayList<>();

        logger.info("检索课表");

        //查询这个学校的教师
        String sql = "SELECT id,name FROM `teacher` WHERE `school_id`  =?";
        logger.info("查询这个学校的所有教师 SQL ={}", sql);
        Map<String, Object> teachingMap = teachingClassesTemplate.queryIdMap(sql, "name", "id", schoolId);
        logger.info("教师map大小 = {}", teachingMap.size());

        //查询这个学校的科目
        sql = "select id,name from `course` WHERE `school_id`  = ? ";
        logger.info("查询这个学校的科目 SQL ={}", sql);
        Map<String, Object> courseMap = teachingClassesTemplate.queryIdMap(sql, "name", "id", schoolId);
        logger.info("科目map大小 = {}", courseMap.size());

        //查询这个学校的班级
        sql = "select c.id,c.`name`    from `classes` c  WHERE c.`school_id`  = ?";
        logger.info("查询这个学校的班级 SQL ={}", sql);
        Map<String, Object> classMap = teachingClassesTemplate.queryIdMap(sql, "name", "id", schoolId);
        logger.info("班级map大小 = {}", classMap.size());

        //继续上传上来的课表信息
        List<Map<String, Object>> timetableList = (List<Map<String, Object>>) JSON.parse(timetable);
        //行数
        Integer index = 0;

        //循环没个班级的课表信息
        for (Map<String, Object> map : timetableList) {

            //课表
            List<Map<String, Object>> kebiaoList = (List<Map<String, Object>>) JSON.parse(map.get("list").toString());
            //循环一节课的信息
            for (Map<String, Object> kebiaoMap : kebiaoList) {

                //错误信息map
                Map<String, Object> errorMap = new HashMap<>();
                //判断班级是否存在
                if (!classMap.containsKey(((String) map.get("name")).trim())) {
                    logger.info("班级不存在");
                    errorMap.put("className", map.get("name"));
                    errorMap.put("index", index);
                }
                //科目
                String courseName = "";
                //教师
                String teacherName = "";

                //判断上传的参数是否为空
                if (kebiaoMap.containsKey("course_name")) {
                    courseName =  ((String) kebiaoMap.get("course_name")).trim();
                }
                //判断上传的参数是否为空
                if(kebiaoMap.containsKey("teacher_name")){
                    teacherName =  ((String) kebiaoMap.get("teacher_name")).trim();
                }

                //判断科目是否存在
                if (!StringUtils.isEmpty(courseName)&&!courseMap.containsKey(courseName)) {
                    logger.info("科目不存在");
                    errorMap.put("className", map.get("name"));
                    errorMap.put("x", kebiaoMap.get("x"));
                    errorMap.put("y", kebiaoMap.get("y"));
                    errorMap.put("subjectName", kebiaoMap.get("course_name"));
                    errorMap.put("index", index);
                }
                //教师是否存在
                if (!StringUtils.isEmpty(teacherName)&&!teachingMap.containsKey(teacherName)) {
                    logger.info("教师不存在");
                    errorMap.put("className", map.get("name"));
                    errorMap.put("x", kebiaoMap.get("x"));
                    errorMap.put("y", kebiaoMap.get("y"));
                    errorMap.put("teacherName", kebiaoMap.get("teacher_name"));
                    errorMap.put("index", index);
                }

                //判断map是否为空
                if (!errorMap.isEmpty()) {
                    errorList.add(errorMap);
                }

            }
            //行数自增长
            index++;
        }
        //判断错误信息大于0
        if (errorList.size() > 0) {
            logger.info("有错误信息");
            return new Result(CodeUtil.RETRIEVE_AND_REPORT_ERRORS, errorList);
        }

        return new Result();
    }

    @Override
    public Result addTimetable(String schoolId, String timetable) {

        logger.info("添加课表");

        //查询这个学校的教师
        String sql = "SELECT id,name FROM `teacher` WHERE `school_id`  =?";
        logger.info("查询这个学校的所有教师 SQL ={}", sql);
        Map<String, Object> teachingMap = teachingClassesTemplate.queryIdMap(sql, "name", "id", schoolId);
        logger.info("教师map大小 = {}", teachingMap.size());

        /*此代码不要删除，后续版本迭代用的着
        //查询这个学校的科目
        sql = "select id,name from `course` WHERE `school_id`  = ? ";
        logger.info("查询这个学校的科目 SQL ={}",sql);
        Map <String,Object> courseMap = teachingClassesTemplate.queryIdMap(sql,"name","id",schoolId);
        logger.info("科目map大小 = {}",courseMap.size());*/

        //查询这个学校的班级
        sql = "select c.id,c.`name`  name  from `classes` c  WHERE c.`school_id`  = ?";
        logger.info("查询这个学校的班级 SQL ={}", sql);
        Map<String, Object> classMap = teachingClassesTemplate.queryIdMap(sql, "name", "id", schoolId);
        logger.info("班级map大小 = {}", classMap.size());

        //查询学校的上课节次
        ClassDay cd = classDayRepository.findBySchoolId(Integer.valueOf(schoolId));

        //要添加的的课表
        List<Timetable> list = new ArrayList<Timetable>();
        //要删除的班级信息
        StringBuffer classs = new StringBuffer();

        //继续上传上来的课表信息
        List<Map<String, Object>> timetableList = (List<Map<String, Object>>) JSON.parse(timetable);
        //循环没个班级的课表信息
        for (Map<String, Object> map : timetableList) {

            List<Map<String, Object>> kebiaoList = (List<Map<String, Object>>) JSON.parse(map.get("list").toString());

            for (Map<String, Object> kebiaoMap : kebiaoList) {

                logger.info("className = {}", map.get("name"));
                logger.info("x = {}", kebiaoMap.get("x"));
                logger.info("y = {}", kebiaoMap.get("y"));
                logger.info("subjectName = {}", kebiaoMap.get("course_name"));
                logger.info("teacherName = {}", kebiaoMap.get("teacher_name"));

                if (StringUtils.isEmpty(kebiaoMap.get("course_name")) || !kebiaoMap.containsKey("teacher_name")) {
                    continue;
                }
                //创建课表实体
                Timetable t = new Timetable();
                //班级id
                t.setClassId((int) classMap.get(map.get("name")));
                //科目
                t.setCourseName(kebiaoMap.get("course_name").toString().trim());
                //教师名字
                t.setTeacherName(kebiaoMap.get("teacher_name").toString().trim());
                //坐标x,星期
                t.setX(Integer.valueOf(kebiaoMap.get("x").toString().trim()));
                //坐标y,节次
                t.setY(Integer.valueOf(kebiaoMap.get("y").toString().trim()));
                //学校id
                t.setSchoolId(Integer.valueOf(schoolId));
                //下周是否需要生效（0不需要，1需要）
                t.setNextStatic(0);
                //获取教师姓名
                String teacherName = kebiaoMap.get("teacher_name").toString().trim();
                //判断教师是否为空
                if (StringUtils.isEmpty(teacherName)) {
                    //教师id
                    t.setTeacherId(0);
                } else {
                    //教师id
                    t.setTeacherId((int) teachingMap.get(teacherName));
                }


                //添加到集合
                list.add(t);
            }

            classs.append(classMap.get(map.get("name").toString().trim())).append(",");
        }
        //转为String类型
        String classid = classs.toString();
        //去掉最后一个字符
        classid = classid.substring(0, classid.length() - 1);
        //删除班级课表SQL
        sql = "DELETE FROM `cloud_window`.`timetable` WHERE class_id in(" + classid + ");";
        teachingClassesTemplate.updateByParameter(sql);

        //重新添加课表信息
        timetableRepository.saveAll(list);
        sql = " DELETE FROM  class_rollcall WHERE  class_id in(" + classid + ");";
        teachingClassesTemplate.updateByParameter(sql);//删除课堂点名里面的课表节次
        String sql1 = "INSERT INTO class_rollcall(class_id,NAME,school_id,add_time,rolltime,stanza)  " +
                " SELECT s.class_id,CONCAT('第',s.y+1,'节 ',s.course_name,'/',s.teacher_name) section,s.school_id,NOW(), CONCAT(start_time,'-',end_time) TIME,s.y FROM timetable s , attend_class_time " +
                "  t WHERE s.y=t.current_section AND  s.x=IF((SELECT DAY FROM class_day WHERE  school_id=s.school_id LIMIT 1)<s.x+1,-1,IF(DATE_FORMAT(NOW(),'%w')=0,6,DATE_FORMAT(NOW(),'%w')-1)) AND s.school_id=t.school_id " +
                "  and s.school_id=? AND s.class_id IN(" + classid + ") ORDER BY s.school_id,s.class_id,s.y";
        teachingClassesTemplate.updateByParameter(sql1, schoolId);//修改过后的课表重新添加到课堂点名里面
        String sql2 = "SELECT GROUP_CONCAT(id) string FROM bancard WHERE school_id=?";
        String s = attendClassTimeJdbc.queryString(sql2, new Object[]{schoolId});
        classCardFieldService.pushClassCard(s, "timetableflag", "1");
        classCardService.pushClassCard(s);
        return new Result();
    }

    @Override
    public Result findClassTimetable(String classid, String schoolId) {

        logger.info("查询班级课表");

        /*String sql = "select id string from classes where class_teacher_id = ?";
        //要查询的班级课表
        String  classid = teachingClassesTemplate.queryString(sql ,teacherId);*/
        List<Map<String, Object>> timetableList = null;
        if (StringUtils.isEmpty(classid)) {
            String sql = "select id,name  from classes where  school_id= ?";
            timetableList = teachingClassesTemplate.queryListMap(sql, schoolId);

            for (Map<String, Object> map : timetableList) {
                //查询班级课表的sql
                sql = "select id,course_name,teacher_name,x,y,class_id,school_id from timetable where class_id=? GROUP BY x ,y ";
                List<Map<String, Object>> list = teachingClassesTemplate.queryListMap(sql, map.get("id"));

                map.put("list", list);
            }

        } else {
            String sql = "select id,name  from classes where  id= ?";
            timetableList = teachingClassesTemplate.queryListMap(sql, classid);
            for (Map<String, Object> map : timetableList) {
                //查询班级课表的sql
                sql = "select id,course_name,teacher_name,x,y,class_id,school_id from timetable where class_id=? GROUP BY   y,x ";
                List<Map<String, Object>> list = teachingClassesTemplate.queryListMap(sql, map.get("id"));

                map.put("list", list);
            }

        }


        return new Result(timetableList);
    }

    @Override
    public Result findTecherTimetable(String teacherId) {
        logger.info("查询教师课表");

        //查询教师的课表
        String sql = "select t.id,t.course_name,t.teacher_name,t.x,t.y,t.class_id,t.school_id ,CONCAT(c.name,'|',t.course_name ) course from timetable t " +
                "left JOIN classes c on(t.class_id=c.id) " +
                "RIGHT JOIN   `teacher` te on( te.`id`=t.teacher_id)    where t.teacher_id=? ";
        logger.info("查询教师课表SQL =  {}", sql);
        List<Map<String, Object>> timetableList = teachingClassesTemplate.queryListMap(sql, teacherId);
        return new Result(timetableList);
    }

    @Override
    public Result findClassSchedule(String teacherId) {

        logger.info("查询班主任班级课表");
        String sql = "select id string from classes where class_teacher_id = ?";
        //要查询的班级课表
        String classid = teachingClassesTemplate.queryString(sql, teacherId);

        //查询班级课表的sql
        sql = "select id,course_name,teacher_name,x,y,class_id,school_id from timetable where class_id=? GROUP BY x ,y ";
        List<Map<String, Object>> list = null;
        try {
            list = teachingClassesTemplate.queryListMap(sql, classid);
        } catch (Exception e) {
            logger.info("该教师不是班主任");
            return new Result();
        }

        return new Result(list);
    }

    @Override
    public Result findClassDay(String schoolId) {
        logger.info("查询上课节次");
        //查看上课节次
        ClassDay classDay = classDayRepository.findBySchoolId(Integer.valueOf(schoolId));
        //上课时间
        Map<String, Object> time = attendClassTimeJdbc.findAttendClassTime(schoolId);
        //上课时间
        List<Map<String, Object>> classTimeList = new ArrayList<Map<String, Object>>();

        Map<String, String> dayMap = getMap();
        //循环天数
        for (int i = 0; i < classDay.getDay(); i++) {

            Map<String, Object> weekMap = new HashMap<>();
            //星期
            String week = "星期" + dayMap.get(String.valueOf((i + 1)));
            logger.info("星期" + dayMap.get(String.valueOf((i + 1))));
            weekMap.put("name", week);

            List<Map<String, Object>> list = new ArrayList<>();
            for (int j = 0; j < classDay.getSecond(); j++) {
                logger.info("第{}课", (j + 1));
                String classTime = time.get(String.valueOf(j)).toString();
                Map<String, Object> classTimeMap = new HashMap<>();
                classTimeMap.put("name", "第" + (j + 1) + "节");
                classTimeMap.put("time", classTime);
                list.add(classTimeMap);
            }
            weekMap.put("list", list);
            classTimeList.add(weekMap);
        }

        return new Result(classTimeList);
    }

    @Override
    public Result findDateTimetable(String teacherId, String time, String schoolId) {
        logger.info("查询这个教师今天的课程");
        //获取今天是星期几
        Integer week = DateUtil.getWeeksInt(time);
        //上课时间
        Map<String, Object> timeMap = attendClassTimeJdbc.findAttendClassTime(schoolId);
        //查询SQL
        String sql = "select t.id,t.course_name,t.teacher_name,t.x,t.y,t.class_id,t.school_id,c.`name` className from timetable t left join classes c on(c.id=t.class_id) where t.teacher_id=? and t.x=? ORDER BY t.y ";
        //教师今天的课表
        List<Map<String, Object>> timeList = attendClassTimeJdbc.queryListMap(sql, teacherId, week);
        for (Map<String, Object> map : timeList) {
            map.put("classTime", timeMap.get(map.get("y").toString()));
        }

        return new Result(timeList);
    }


    /**
     * ,
     * 中文数字数组
     *
     * @return
     */
    public Map<String, String> getMap() {
        Map<String, String> map = new HashMap<>();
        map.put("1", "一");
        map.put("2", "二");
        map.put("3", "三");
        map.put("4", "四");
        map.put("5", "五");
        map.put("6", "六");
        map.put("7", "日");
        return map;
    }
}
